Skip to content

🐛 fix(cache): reject untrusted cache paths - #213

Merged
gaborbernat merged 4 commits into
tox-dev:mainfrom
gaborbernat:security/lhuom9m1-cache-ownership
Nov 3, 2026
Merged

gaborbernat merged 4 commits into
tox-dev:mainfrom
gaborbernat:security/lhuom9m1-cache-ownership

Conversation

@gaborbernat

@gaborbernat gaborbernat commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

DiskCache.py_info() used cache directories without checking who controlled them, and DiskContentStore.read() trusted their entries. On a shared cache root, another user could make discovery run an executable named by cached metadata. Discovery now declines untrusted directories and entries, and writes cache files without following existing links. This addresses draft advisory ANT-2026-LHUOM9M1.

Cache directory ownership

The old cache lookup and clear paths accepted existing directories without checking their owner or permissions. The new check requires the cache root and both py_info directories to belong to the current user or root and to deny writes by other users. It checks ancestors too; a sticky directory prevents other users from renaming a child they do not own. When the check fails, discovery queries the interpreter without using that disk cache.

Cache entry handling

The old read and write paths accepted any readable entry and followed a link when writing. Entry reads now require a regular file with acceptable ownership and mode. O_NOFOLLOW rejects links and O_NONBLOCK avoids waiting to open a FIFO. Writes use a private temporary file and replace the entry path, so a link there cannot redirect a write. Python creates these temporary files with access limited to the creating user.

Behavior changes

On POSIX, discovery skips a cache in a directory another user owns or can write and logs a warning. It still queries the requested interpreter. If an entry fails the file checks, discovery tries to remove it and queries the interpreter again. A relative cache root is bound to the current directory when DiskCache is constructed. Platforms without os.geteuid, including Windows, retain the existing directory eligibility rule.

Reported by Antigravity: ANT-2026-LHUOM9M1.

DiskCache can load interpreter metadata from a directory another user
controls and then execute the path it names. Check directory and entry
ownership before trusting cached data, and replace entries atomically so
links cannot redirect writes.
@gaborbernat gaborbernat added the bug Something isn't working label Nov 3, 2026
A relative cache root passed ownership checks in one directory while a
later working-directory change sent writes elsewhere. Bind the root when
constructing DiskCache so the checked path is also used for I/O.
@gaborbernat gaborbernat added the security Security fixes and advisories label Nov 3, 2026
@gaborbernat
gaborbernat enabled auto-merge (squash) November 3, 2026 00:53
@gaborbernat
gaborbernat disabled auto-merge November 3, 2026 00:54
@gaborbernat
gaborbernat merged commit 264012c into tox-dev:main Nov 3, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working security Security fixes and advisories

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant